﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DatabaseSimulation
{
    public class TwoPhaseLockingDatabase : Database
    {
        public int DeadLockTimeout { get; private set; }

        public TwoPhaseLockingDatabase(TransactionGenerator transactionGenerator, int numberOfObjects, int numberOfHardDrives, int numberOfCpus, int milliseconds, int deadLockTimeout) : base(transactionGenerator, numberOfObjects, numberOfHardDrives, numberOfCpus, milliseconds)
        {
            this.DeadLockTimeout = deadLockTimeout;
        }

        protected override bool ReadAfterWriteConflict(DatabaseOperation operation)
        {
            ResolveConflict(operation);
            return false;
        }

        protected override bool WriteAfterReadConflict(DatabaseOperation operation)
        {
            ResolveConflict(operation);
            return false;
        }

        protected override bool CheckCanCommitTransaction(Transaction transaction)
        {
            return true;
        }

        protected override void TransactionCommitted(Transaction transaction) { }

        protected override void HandleExclusiveBlock(DatabaseOperation operation)
        {
            throw new NotImplementedException();
        }

        private void ResolveConflict(DatabaseOperation operation)
        {
            if (operation.ElapsedBlockedOnTransactionTime == 0)
            {
                this.CurrentSimulationResult.TransactionBlocks++;
            }
            operation.IncreaseBlockedOnTransactionTime();
            this.CurrentSimulationResult.BlockedOnTransactionTime++;

            if (operation.ElapsedBlockedOnTransactionTime == this.DeadLockTimeout)
            {
                KillTransaction(operation.Transaction);
            }
        }

        protected override void SimulationComplete(int mpl) { }
    }
}
